/**
 * 2010(c) Copyright Oceansoft Information System Co.,LTD. All rights reserved.
 * <p>
 * Compile: JDK 1.6+
 * <p>
 * 版权所有(C)：江苏欧索软件有限公司
 * <p>
 * 公司名称：江苏欧索软件有限公司
 * <p>
 * 公司地址：中国苏州科技城青山路1号
 * <p>
 * 网址: http://www.oceansoft.com.cn
 * <p>
 * 作者: 090922(陈伟)
 * <p>
 * 文件名: com.oceansoft.mobile.api.news.service.impl.NewsServiceImpl.java
 * <p>
 * 类产生时间: 14-4-29 上午11:05
 * <p>
 * 负责人: 090922(陈伟)
 * <p>
 * Email:javacspring@gmail.com
 * <p>
 * 所在组 : 掌上公安应用平台
 * <p>
 * 所在部门: 开发部--手持技术部
 * <p>
 * <p>
 */
package com.oceansoft.mobile.econsole.modules.news.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.oceansoft.mobile.econsole.cache.redis.CacheBaseService;
import com.oceansoft.mobile.econsole.common.constant.Constant;
import com.oceansoft.mobile.econsole.common.util.DateUtil;
import com.oceansoft.mobile.econsole.common.util.FileUtils;
import com.oceansoft.mobile.econsole.common.util.HttpClientUtil;
import com.oceansoft.mobile.econsole.common.util.StringUtils;
import com.oceansoft.mobile.econsole.common.util.web.PageUtil;
import com.oceansoft.mobile.econsole.modules.base.entity.ApiPager;
import com.oceansoft.mobile.econsole.modules.base.entity.Pager;
import com.oceansoft.mobile.econsole.modules.base.entity.Query;
import com.oceansoft.mobile.econsole.modules.base.entity.Result;
import com.oceansoft.mobile.econsole.modules.channel.entity.Channel;
import com.oceansoft.mobile.econsole.modules.jlapi.entity.WeChatMediaMsg;
import com.oceansoft.mobile.econsole.modules.jlapi.entity.WechatMessage;
import com.oceansoft.mobile.econsole.modules.member.persistence.IWtMemberMapper;
import com.oceansoft.mobile.econsole.modules.news.entity.ApiNews;
import com.oceansoft.mobile.econsole.modules.news.entity.News;
import com.oceansoft.mobile.econsole.modules.news.persistence.INewsMapper;
import com.oceansoft.mobile.econsole.modules.news.service.INewsService;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.DigestUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

/**
 * 新闻业务处理组件实现类
 *
 * @author: chenw
 * @time: 14-4-29 上午11:05
 */
@Service
public class NewsServiceImpl extends CacheBaseService implements INewsService {

    @Resource
    private INewsMapper newsMapper;

    @Resource
    private IWtMemberMapper wtMemberMapper;

    @Override
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    public Result save(News news) {
        if (StringUtils.isBlank(news.getTitle())) {
            return new Result(Result.FAILURE, "数据写入失败，错误：新闻标题缺失！");
        }
        if (StringUtils.isBlank(news.getPubDept())) {
            return new Result(Result.FAILURE, "数据写入失败，错误：部门信息缺失！");
        }
        if (0 == news.getChannelId()) {
            return new Result(Result.FAILURE, "数据写入失败，错误：栏目信息缺失！");
        }
        if (StringUtils.isBlank(news.getContent())) {
            return new Result(Result.FAILURE, "数据写入失败，错误：新闻内容缺失！");
        }
        //图片新闻
        if (1 == news.getImgNews() && StringUtils.isBlank(news.getImgUrl())) {
            return new Result(Result.FAILURE, "数据写入失败，错误：图片新闻图片地址缺失！");
        }
        news.setCreateTime(new Date());
        if (StringUtils.isBlank(news.getOrginalUrl())) {
            news.setOrginalUrl("");
        }
        //网页内容转码
        try {
            parseNewsContent(news);
        } catch (Exception ex) {
            return new Result(Result.FAILURE, "数据写入失败，错误：内容转码失败！");
        }
        System.out.println("\n\n=========================>" + news.getContent());
        long id = newsMapper.save(news);
        if (id > 0) {
            return new Result("数据写入成功！");
        }
        return new Result(Result.FAILURE, "数据保存失败");
    }

    /**
     * 解析网页内容
     *
     * @param news 原始网页数据
     * @return 转码后内容
     * @throws IOException
     */
    private News parseNewsContent(News news) throws IOException {
        Document document = Jsoup.parse(news.getContent(), "utf-8");
        Elements ps = document.getElementsByTag("p");
        StringBuilder content = new StringBuilder();
        boolean summary_is_empty = news.getSummary().trim().isEmpty();
        for (Element p : ps) {
            Elements imgs = p.getElementsByTag("img");
            if (imgs.size() > 0) {//有图片
                content.append("<p>");
                for (Element img : imgs) {
                    content.append("<img src=\"../images/img_default.png\" ").append("origi_url=\"").append(img.attr("src")).append("\"").append("/>");
                }
                content.append("</p>");
            } else {
                String _p_text = p.text().trim().replace("\t", "").replaceAll(" ", "");
                if (_p_text.length() > 0) {
                    content.append("<p>").append(_p_text).append("</p>");
                }
                if (summary_is_empty) {
                    news.setSummary(_p_text.substring(0, _p_text.length() > 100 ? 100 : _p_text.length()));
                    summary_is_empty = false;
                }
            }
        }
        news.setContent(content.toString());
        return news;
    }

    @Override
    public List<Channel> loadAllChannels() {
        return newsMapper.loadAllChannels();
    }

    @Override
    public Result loadNewsByPage(int channelId, int pageIndex, String url) {
        url = "app:news:" + url;
        if (super.exists(url)) {
            JSONObject result = (JSONObject) super.getObject(url);
            int size = result.getJSONObject("body").getJSONArray("list").size();
            if (size > 0)
                return new Result(Result.SUCC, super.getObject(url));
            else
                return new Result(Result.FAILURE, Result.FAILURE, "暂无数据");
        }
        HashMap<String, Object> result = new HashMap<String, Object>(2);
        int total = newsMapper.loadCountByCondition(channelId);
        //加载新闻列表数据
        PageHelper.startPage(pageIndex, Constant.PAGE_SIZE, true);
        Page<News> page = (Page<News>) newsMapper.loadListByCondition(channelId);
        List<News> list = page.getResult();
        final ApiPager<News> pager = new ApiPager<News>(Constant.API_PAGE_SIZE, pageIndex, total, list);
        if (pageIndex > 1) { //大于第一页则只加载列表数据
            result.put("header", null);
        } else {//第一页加载top3图片+每一页列表数据
            PageHelper.startPage(1, 3, false);
            Page<News> page3 = (Page<News>) newsMapper.loadChannelTopPicNews(channelId);
            //加载Top3图片新闻
            result.put("header", page3.getResult());
        }
        result.put("body", pager);

        //app后台发布的转成1，网上公安后台发布的转成0
        if (!CollectionUtils.isEmpty(list)) {
            for (News n : list) {
                if (null != n.getPubDept()) {
                    n.setPubDept(n.getPubDept().equals("app后台_V2") ? "1" : "0");
                }
            }
        }

        if (list.size() > 0) {
            super.cache(url, result, 10 * 60);//新闻数据缓存10分钟
            return new Result(result);
        } else {
            super.cache(url, result, 30);//返回无数据则结果缓存30s
            return new Result(Result.FAILURE, "暂无数据");
        }
    }

    @Override
    public Result loadNewsById(String id) {

        String url = configInfo.getServiceInterfaceAddress() + "/news/news/" + id;
        String res = null;
        try {
            res = HttpClientUtil.doGet(url);
        } catch (IOException e) {
        }

        JSONObject object = JSON.parseObject(res);
        Preconditions.checkArgument(object.getBooleanValue("succ"), "获取接口数据返回失败");
        ApiNews data = object.getJSONArray("data").getObject(0, ApiNews.class);
        return new Result(Result.SUCC, data);
    }

    @Override
    public Result loadNewsById(long id) {
        return null;
    }

    @Override
    public Pager<Channel> findChannelByPage(Query query) {
        PageHelper.startPage(query.getPageNum(), query.getNumPerPage(), true);
        Page<Channel> page = (Page<Channel>) newsMapper.loadChannelListByCondition(query);
        return PageUtil.page2pager(page, query);
    }

    @Override
    public Result loadTopImgNews(int topSize) {
        PageHelper.startPage(1, 3, false);
        Page<News> page = (Page<News>) newsMapper.loadTopImgNews();
        if (!CollectionUtils.isEmpty(page.getResult())) {
            for (News n : page.getResult()) {
                if (null != n.getPubDept())
                    n.setPubDept(n.getPubDept().equals("app后台_V2") ? "1" : "0");
            }
        }
        return new Result(page.getResult());
    }

    @Override
    public Pager<News> loadAllNewsByPage(Query query) {
        PageHelper.startPage(query.getPageNum(), query.getNumPerPage(), true);
        Page<News> page = (Page<News>) newsMapper.loadNewByCondition(query);
        return PageUtil.page2pager(page, query);
    }

    @Override
    public Result deleteNews(int newsId) {
        newsMapper.deleteNewsById(newsId);
        return new Result();
    }

    @Override
    public Result updateNews(News news) {
        int id = newsMapper.updateNews(news);
        if (id == 1) {
            return new Result(Result.SUCC, "更新成功");
        }
        return new Result(Result.FAILURE, "更新失败");
    }

    @Override
    public Result pubNews(int newId) {
        News news = newsMapper.findById(newId);
        int id = newsMapper.pubNews(news);
        if (id == 1) {
            this.sendCustomSmg(news);
            return new Result(Result.SUCC, "发布成功");
        }
        return new Result(Result.FAILURE, "发布失败");
    }

    /**
     * 发送客服消息
     *
     * @param news
     */
    private void sendCustomSmg(News news) {

        WeChatMediaMsg.PubMsg pubMsg = WeChatMediaMsg.PubMsg.build()
                .setTitle(news.getTitle())
                .setDescription(news.getSummary())
                .setUrl(configInfo.getApiNewsUrl() + news.getId())
                .setPicurl(news.getImgUrl());
//                .setUrl("http://gawx.daqing.gov.cn/econsole/api/goToNewDetail/2865")
//                .setPicurl("http://gawx.daqing.gov.cn/econsole/upload/news/571848ebe902282b2eb81cee3f9fed63.jpg");

        WeChatMediaMsg weChatMediaMsg = WeChatMediaMsg.build()
                .setCustomMsg(Lists.newArrayList(pubMsg))
                .setMsgType(WeChatMediaMsg.MsgType.CUSTOM);

        System.out.println(JSON.toJSONString(weChatMediaMsg.getCustomMsg()));
        HttpClientUtil.doPostString(configInfo.getWeChatMediaSendUrl(), weChatMediaMsg);
    }

    /**
     * 发送图文消息
     *
     * @param openId
     * @param news
     */
    private void sendMediaMsg(String openId, News news) {
        //推送图文新闻
        WeChatMediaMsg weChatMediaMsg = WeChatMediaMsg.build()
                .createMediaByNews(Lists.newArrayList(news))
                .setOpenId(openId)
                .setMsgType(WeChatMediaMsg.MsgType.MEDIA);
        HttpClientUtil.doPostString(configInfo.getWeChatMediaSendUrl(), weChatMediaMsg);
    }

    /**
     * 发送模板消息
     *
     * @param openId
     * @param news
     */
    private void sendTemplateSmg(String openId, News news) {

        WechatMessage wechatMessage = new WechatMessage();
        wechatMessage.setOpenId(openId);
        wechatMessage.setTempId(WechatMessage.WECHAT_TEMPLATEID);
        wechatMessage.setUrl(configInfo.getApiNewsUrl() + news.getId());
//        wechatMessage.setUrl("http://gawx.daqing.gov.cn/econsole/api/goToNewDetail/2865");
        HashMap<String, String[]> keyMap = new HashMap<>();
        keyMap.put("first", new String[]{news.getTitle(), "#173177"});
        keyMap.put("keyword1", new String[]{news.getSummary(), "#173177"});
        keyMap.put("keyword2", new String[]{DateUtil.date2String(news.getCreateTime(), "yyyy-MM-dd"), "#173177"});
        wechatMessage.setParams(keyMap);
        HttpClientUtil.doPostString(configInfo.getWechatSendUrl(), wechatMessage);
    }


    @Override
    public Result saveNewsBeforePub(News news) {
        if (StringUtils.isBlank(news.getTitle())) {
            return new Result(Result.FAILURE, "数据写入失败，错误：新闻标题缺失！");
        }
        if (StringUtils.isBlank(news.getPubDept())) {
            return new Result(Result.FAILURE, "数据写入失败，错误：部门信息缺失！");
        }
        if (0 == news.getChannelId()) {
            return new Result(Result.FAILURE, "数据写入失败，错误：栏目信息缺失！");
        }
        if (StringUtils.isBlank(news.getContent())) {
            return new Result(Result.FAILURE, "数据写入失败，错误：新闻内容缺失！");
        }
        //图片新闻
        if (1 == news.getImgNews() && StringUtils.isBlank(news.getImgUrl())) {
            return new Result(Result.FAILURE, "数据写入失败，错误：图片新闻图片地址缺失！");
        }
        news.setCreateTime(new Date());
        if (StringUtils.isBlank(news.getOrginalUrl())) {
            news.setOrginalUrl("");
        }
        long id = newsMapper.save(news);
        if (id > 0) {
            return new Result("数据写入成功！");
        }
        return new Result(Result.FAILURE, "数据保存失败");
    }

    @Override
    public Result loadNewsByPage(String channel, int pageNum) {
        String url = configInfo.getServiceInterfaceAddress() + "/news/page?"
                + "ps=" + Constant.API_PAGE_SIZE + "&pi=" + pageNum + "&kw=" + channel
                + "&q_deleted_s_eq=N&q_public_time_d_ge=2016-01-01&q_public_time_d_le=2017-12-12";
        ApiPager apiPager = HttpClientUtil.doGet(url, ApiNews.class);
        Result result = new Result();
        result.setSucc(Result.SUCC);
        result.setData(apiPager);
        result.setMsg("");
        result.setHasNext(apiPager.isHasNext());
        return result;
    }

    @Override
    public String editorUpload(MultipartHttpServletRequest request) throws Exception {
        Iterator<String> itr = request.getFileNames();
        String newFileName = null;
        String photoUrl = null;
        while (itr.hasNext()) {
            MultipartFile mpf = request.getFile(itr.next());
            newFileName = String.format("%s%s", DigestUtils.md5DigestAsHex(mpf.getBytes()), FileUtils.getExtName(mpf.getOriginalFilename()));
            photoUrl = String.format("%s/%s", configInfo.getFileUploadRootPath(), "news");
            //存储文件至文件系统
            mpf.transferTo(FileUtils.createFile(new File(photoUrl), newFileName));
        }
        return "{'err':'','msg':{'url':'" + configInfo.getFileDownloadUrl("news/" + newFileName) + "'}}";
    }
}
